package ru.ipo.dces.plugins.multivariateplugin;

import java.util.*;

import info.clearthought.layout.TableLayout;
import ru.ipo.dces.exceptions.GeneralRequestFailureException;
import ru.ipo.dces.pluginapi.Plugin;
import ru.ipo.dces.pluginapi.PluginEnvironment;
import ru.ipo.dces.utils.ResultUtils;
import ru.ipo.dces.utils.UIUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.List;

public class MultivariatePlugin extends JPanel implements Plugin {

    public PluginEnvironment env;
    private LinkedList<Integer> properties;      // Настройки прошлых установок плагина
    private boolean isManyAnswers;
    private List<JToggleButton> buttonList;         // Кнопки выбора варианта решения

    public MultivariatePlugin(PluginEnvironment env) {
        this.env = env;
        String ans = env.getProblem().getString("isManyAnswers");
        isManyAnswers = ans != null && ans.trim().equals("true");

        properties = env.getStorage().getData("properties");
        if (properties == null)
            properties = new LinkedList<Integer>();

        initInterface();
    }

    // Создаёт кнопку подтверждения со слушателем.
    private JButton getSubmitButton() {
        JButton button = new JButton("Отправить решение");

        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                boolean isSelected = false;
                String answer = "";
                for (int i = 0; i < buttonList.size(); i++) {
                    if (buttonList.get(i).isSelected()) {
                        answer += i + " ";
                        isSelected = true;
                    }
                }

                if (!isSelected) {
                    JOptionPane.showMessageDialog(MultivariatePlugin.this, "Вы должны выбрать вариант ответа");
                    return;
                }

                answer = answer.trim();

                //Убедиться, что участник действительно собирается отправить решение.
                if (JOptionPane.showConfirmDialog(MultivariatePlugin.this, "Вы уверены, что хотите отправить решение?",
                        "Отправка решения", JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION)
                    return;

                try {
                    env.submitSolution(ResultUtils.newMap("answer", answer));
                    JOptionPane.showMessageDialog(MultivariatePlugin.this, "Решение отослано");
                } catch (GeneralRequestFailureException e1) {
                    JOptionPane.showMessageDialog(MultivariatePlugin.this, "Не удалось отправить решение");
                }
            }
        });

        return button;
    }

    // Возвращает список возможных ответов.
    private ArrayList<JComponent> getOptionList() {
        ArrayList<JComponent> JComponentList = new ArrayList<JComponent>();

        // Список ресурсов, начинающихся с answerOption/
        List<String> answerOptionList = new ArrayList<String>();
        List<String> temp = env.getProblem().listNames();

        for (String str : temp)
            if (str.startsWith("option") && !str.endsWith("~type"))
                answerOptionList.add(str);

        if (answerOptionList.isEmpty())
            return null;

        Collections.sort(answerOptionList);
        for (String option : answerOptionList)
            JComponentList.add(UIUtils.getDisplayComponent(env.getProblem(), option));
        return JComponentList;
    }


    private void initInterface() {
        List<JComponent> optionsList = getOptionList();
        if (optionsList == null) {
            add(new JLabel("Ошибка: список вариантов ответов не найден."));
            return;
        }

        buttonList = new ArrayList<JToggleButton>();
        int index = 0;
        if (isManyAnswers)
            //noinspection UnusedDeclaration
            for (JComponent o : optionsList) {
                JCheckBox button = ButtonFactory.getDecoratedJCheckButton();
                button.setActionCommand(Integer.toString(index));
                buttonList.add(button);
                index++;
            }
        else {
            ButtonGroup group = new ButtonGroup();
            //noinspection UnusedDeclaration
            for (JComponent o : optionsList) {
                JRadioButton button = ButtonFactory.getDecoratedJRadioButton();
                button.setActionCommand(Integer.toString(index));
                buttonList.add(button);
                group.add(button);
                index++;
            }
        }

        setLayout(new BorderLayout());
        add(env.getStatementPanel(), BorderLayout.NORTH);

        double[] temp = new double[optionsList.size()];
        Arrays.fill(temp, TableLayout.PREFERRED);
        double[] tableLayoutHeight = new double[temp.length + 2];
        for(int i = 0; i < tableLayoutHeight.length; i++) {
            if (i == 0) {
                tableLayoutHeight[i] = TableLayout.FILL;
                continue;
            }
            if (i == tableLayoutHeight.length - 1) {
                tableLayoutHeight[i] = TableLayout.FILL;
                continue;
            }
            tableLayoutHeight[i] = temp[i - 1];
        }

        JPanel checkPanel = new JPanel();
        checkPanel.setLayout(new TableLayout(new double[] {TableLayout.PREFERRED, TableLayout.FILL}, tableLayoutHeight));

        for(int i = 0; i < buttonList.size(); i++) {
            checkPanel.add(buttonList.get(i), "0 " + (i + 1));

            checkPanel.add(optionsList.get(i), "1 " + (i + 1) + " l c");
        }
        add(checkPanel, BorderLayout.CENTER);


        for (Integer i : properties)
                buttonList.get(i).setSelected(true);

        for (JToggleButton button : buttonList) {
            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent actionEvent) {
                    System.out.println(Thread.currentThread().hashCode());
                    int buttonIndex = Integer.parseInt(actionEvent.getActionCommand());

                    // Удалить или добавить из properties индекс кнопки, которая больше не нажата
                    if (buttonList.get(buttonIndex).isSelected()) {
                        if (properties.contains(buttonIndex))
                            return;
                        properties.add(buttonIndex);
                    } else {
                        int index = properties.indexOf(buttonIndex);
                        if (index >= 0)
                            properties.remove(index);
                    }

                    env.getStorage().setData("properties", properties);
                    env.getStorage().flush();
                }
            });
        }

        JButton submit = getSubmitButton();
        add(submit, BorderLayout.SOUTH);
    }

    public JPanel getPanel() {
        //необходимо вернуть окно, на котором отображается плагин.
        //Возвращаем окно, которым является как раз текущий объект
        return this;
    }

    public void activate() {
        //вызывается при выборе задачи. Ничего не будем делать, только напишем отладочный вывод:
        System.out.println("Plugin activated");
    }

    public void deactivate() {
        //вызывается если участник выбрал другую задачу. Ничего не будем делать, только напишем отладочный вывод:
        System.out.println("Plugin deactivated");
    }
}

